#ifndef __MARS_GRAPHICS_SHADER_H__
#define __MARS_GRAPHICS_SHADER_H__

#include <d3d11.h>

#include "MarsObject.h"
#include "MarsShaderType.h"
#include "MarsShaderParameter.h"

namespace Graphics
{

class Shader : public Core::Object
{
	friend class ShaderCompiler;

public:
									Shader( ShaderType eType, const char* pcszFileName, const char* pcszEntry, const char* pcszShaderModel );
	virtual							~Shader();

	Core::uint32					GetHash() const;
	const std::string&				GetFileName() const;
	const std::string&				GetEntry() const;
	const std::string&				GetShaderModel() const;
	ID3DBlob*						GetBuffer() const;

	void							SetParameter( ShaderSemantic semantic, void* pBuffer );

	void							UploadParameters();

	virtual void					Release();

	virtual bool					PostCompile() = 0;

protected:
	virtual void					SetCBufferToContext() = 0;
	void							GenerateUserDataBuffer();
	
protected:
	ShaderType						m_eShaderType;
	std::string						m_strFileName;
	std::string						m_strEntry;
	std::string						m_strShaderModel;
	Core::uint32					m_iHash;
	ID3DBlob*						m_pBuffer;

	typedef std::map< Core::uint32, ShaderParameter* >	ParameterMap;
	typedef ParameterMap::iterator						ParameterMapItr;
	typedef ParameterMap::const_iterator				ParameterMapConstItr;

	ParameterMap					m_mapParameters;

	typedef struct _ShaderSlot
	{
		int							Index;
		int							Size;
		Core::uint8*				Buffer;
		VRamBuffer*					VBuffer;
		bool						Dirty;
	} ShaderSlot;

	typedef std::map< int, ShaderSlot > ShaderSlotMap;
	typedef ShaderSlotMap::iterator ShaderSlotMapItr;
	typedef ShaderSlotMap::const_iterator ShaderSlotMapConstItr;

	ShaderSlotMap					m_mapShaderSlots;
};

inline Shader::~Shader()
{

}

inline Core::uint32 Shader::GetHash() const
{
	return m_iHash;
}

inline const std::string& Shader::GetFileName() const
{
	return m_strFileName;
}

inline const std::string& Shader::GetEntry() const
{
	return m_strEntry;
}

inline const std::string& Shader::GetShaderModel() const
{
	return m_strShaderModel;
}

inline ID3DBlob* Shader::GetBuffer() const
{
	return m_pBuffer;
}

} // end of namespace Graphics

#endif // end of #ifndef __MARS_GRAPHICS_SHADER_H__